import akshare as ak
import pandas as pd
import numpy as np
import time
from datetime import datetime
import os
# from send_mail import send_email

os.environ["http_proxy"] = ""
os.environ["https_proxy"] = ""

# 参数
TURNOVER_MIN = 5
TURNOVER_MAX = 10
MCAP_MAX = 200e8
PRICE_MIN = 3
PRICE_MAX = 30
DEVIATION_RATIO10 = 0.1
DEVIATION_MUL30 = 0.7
RSI_PERIOD = 14

# 获取全市场快照
spot_all = ak.stock_zh_a_spot_em()
spot_filtered = spot_all[
    (spot_all["换手率"].astype(float).between(TURNOVER_MIN, TURNOVER_MAX)) &
    (spot_all["流通市值"].astype(float) * 1e8 <= MCAP_MAX) &
    (spot_all["最新价"].astype(float).between(PRICE_MIN, PRICE_MAX)) &
    (~spot_all["名称"].str.startswith("ST")) &
    (~spot_all["代码"].str.startswith(("300", "301")))
]

codes = spot_filtered["代码"].tolist()
spot_map = spot_filtered.set_index("代码").to_dict(orient="index")

results_A = []  # 策略A_阴线回调
results_B = []  # 策略B_低价反弹
results_C = []  # 多指标综合策略

for code in codes:
    try:
        daily = ak.stock_zh_a_daily(symbol=code, adjust="qfq")
        if len(daily) < 35:
            continue
        for w in [5,10,20,30]:
            daily[f"ma{w}"] = daily["close"].rolling(w).mean()
        daily["vol_ma5"] = daily["volume"].rolling(5).mean()
        latest = daily.iloc[-1]
        spot = spot_map.get(code)
        if not spot:
            continue

        turnover = float(spot["换手率"])
        mcap = float(spot["流通市值"]) * 1e8
        name = spot["名称"]

        # -------- 技术指标 --------
        delta = daily["close"].diff()
        up = delta.clip(lower=0)
        down = -1 * delta.clip(upper=0)
        roll_up = up.rolling(RSI_PERIOD).mean()
        roll_down = down.rolling(RSI_PERIOD).mean()
        rsi = 100 - (100 / (1 + roll_up / roll_down))
        latest_rsi = rsi.iloc[-1]

        ema12 = daily["close"].ewm(span=12, adjust=False).mean()
        ema26 = daily["close"].ewm(span=26, adjust=False).mean()
        dif = ema12 - ema26
        dea = dif.ewm(span=9, adjust=False).mean()
        macd_cross = dif.iloc[-1] > dea.iloc[-1] and dif.iloc[-2] < dea.iloc[-2]

        ma5_slope = daily["ma5"].iloc[-1] - daily["ma5"].iloc[-2]
        ma10_slope = daily["ma10"].iloc[-1] - daily["ma10"].iloc[-2]
        vol_ratio = daily["volume"].iloc[-1] / daily["vol_ma5"].iloc[-1]

        # -------- 策略A_阴线回调 --------
        cond_A = latest["close"] < latest["open"] \
                 and latest["close"]*(1-DEVIATION_RATIO10) <= latest["ma10"]*(1+DEVIATION_RATIO10)
        if cond_A:
            results_A.append({"code":code,"name":name,"close":latest["close"]})

        # -------- 策略B_低价反弹 --------
        cond_B = PRICE_MIN <= latest["close"] <= 10 \
                 and latest["close"] > daily["ma10"].iloc[-1]
        if cond_B:
            results_B.append({"code":code,"name":name,"close":latest["close"]})

        # -------- 策略C_多指标综合 --------
        cond_C = all([
            latest["close"] < latest["open"],
            latest["ma20"] < latest["ma5"], latest["ma20"] < latest["ma10"],
            latest["ma30"] < latest["ma5"], latest["ma30"] < latest["ma10"],
            latest["ma10"]*(1-DEVIATION_RATIO10) <= latest["close"] <= latest["ma10"]*(1+DEVIATION_RATIO10),
            latest["close"] > latest["ma20"]*DEVIATION_MUL30, latest["close"] > latest["ma30"]*DEVIATION_MUL30,
            turnover >= TURNOVER_MIN, turnover <= TURNOVER_MAX, mcap <= MCAP_MAX,
            ma5_slope > 0, ma10_slope > 0,
            latest_rsi < 40,
            macd_cross,
            vol_ratio > 1
        ])
        if cond_C:
            results_C.append({"code":code,"name":name,"close":latest["close"],"RSI":round(latest_rsi,2),"vol_ratio":round(vol_ratio,2)})

        time.sleep(0.1)

    except Exception as e:
        print(f"{code} 错误: {e}")
        continue

# -------- 保存 CSV --------
today_str = datetime.today().strftime("%Y_%m_%d")
df_A = pd.DataFrame(results_A)
df_B = pd.DataFrame(results_B)
df_C = pd.DataFrame(results_C)

# 本地测试
df_A.to_csv(f"./output/result_A_{today_str}.csv",index=False,encoding="utf-8-sig")
df_B.to_csv(f"./output/result_B_{today_str}.csv",index=False,encoding="utf-8-sig")
df_C.to_csv(f"./output/result_C_{today_str}.csv",index=False,encoding="utf-8-sig")


# docker 环境
# df_A.to_csv(f"/app/output/result_A_{today_str}.csv",index=False,encoding="utf-8-sig")
# df_B.to_csv(f"/app/output/result_B_{today_str}.csv",index=False,encoding="utf-8-sig")
# df_C.to_csv(f"/app/output/result_C_{today_str}.csv",index=False,encoding="utf-8-sig")

# -------- 发送邮件 --------
# send_email([
#     f"/app/output/result_A_{today_str}.csv",
#     f"/app/output/result_B_{today_str}.csv",
#     f"/app/output/result_C_{today_str}.csv"
# ])

print("✅ 三种策略筛选完成并已发送邮件")
